package fs2

import (
	"fmt"
	"github.com/sirupsen/logrus"
	"mydocker/cgroups/resource"
	"mydocker/common"
	"os"
	"path"
	"strconv"
)

type CpuSubsystem struct {
}

const (
	PeriodDefault = 100000 // 默认周期
	Percent       = 100    // 百分比
)

func (*CpuSubsystem) Name() string {
	return "cpu"
}

func (c *CpuSubsystem) Set(cgroupPath string, res *resource.ResourceConfig) error {
	if res.CpuCFSQuota == 0 {
		return nil
	}
	subsystemCgroupPath, err := getCgroupPath(cgroupPath, true)
	if err != nil {
		logrus.Errorf("get %s path, err %v", cgroupPath, err)
		return err
	}
	// cpu.cfs_period_us & cpu.cfs_quota_us 控制的是 CPU 使用时间，单位是微秒，比如每 1 秒钟，这个进程只能使用 200ms，相当于只能用 20% 的 CPU
	// v2 中直接将 cpu.cfs_period_us & cpu.cfs_quota_us 统一记录到 cpu.max 中，比如 5000 10000 这样就是限制使用 50% cpu
	if res.CpuCFSQuota != 0 {
		if err = os.WriteFile(path.Join(subsystemCgroupPath, "cpu.max"), []byte(fmt.Sprintf("%s %S", strconv.Itoa(PeriodDefault*res.CpuCFSQuota/Percent), PeriodDefault)), common.Perm0644); err != nil {
			logrus.Errorf("set cgroup cpu share fail %v", err)
		}
	}
	return nil
}

func (c *CpuSubsystem) Apply(cgroupPath string, pid int) error {
	return applyCgroup(pid, cgroupPath)
}

func (c *CpuSubsystem) Remove(cgroupPath string) error {
	subsystemCgroupPath, err := getCgroupPath(cgroupPath, false)
	if err != nil {
		logrus.Errorf("get %s path, err %v", cgroupPath, err)
		return err
	}
	return os.RemoveAll(subsystemCgroupPath)
}
